fix(worktree): survive the renderer-era bmad-dev-auto (BMAD-METHOD #2587/#2588)#155
fix(worktree): survive the renderer-era bmad-dev-auto (BMAD-METHOD #2587/#2588)#155pbean wants to merge 1 commit into
Conversation
…587/#2588)
Upstream bmad-dev-auto's SKILL.md is now a two-line shim that runs
`uv run render.py` and follows its stdout; the renderer anchors its
project root on the first _bmad/ dir walking UP from the session cwd,
requires the post-#2285 _bmad/config.toml, and rewrites
_bmad/render/bmad-dev-auto/ with absolute paths baked in. The completion
contract bmad-loop parses is unchanged — the breakage is environmental:
- Worktrees nest under <project>/.bmad-loop/runs/ and never carried a
_bmad/, so render.py silently adopted the MAIN checkout's: rendered
workflows baked main-checkout absolute artifact paths (deferred-work
appends, no-spec fallback artifacts, and step-01 context escaped the
worktree — fallbacks landing where _artifact_dirs never looks) and
every parallel session raced on one shared, delete-rewritten render
dir. provision_worktree now merge-seeds the main repo's _bmad/ config
surface per-file (copy-when-absent: a committed _bmad/ keeps every
tracked file; the gitignored *.user.toml layers — whose absence
hard-HALTs render.py since #2588 — are filled in), never seeds the
regenerated render/, and shields it: one anchored /_bmad exclude when
the checkout had none, per-file rels when merging into an existing
tree.
- /_bmad/render/ is always excluded (seeded or not) so session-rendered
output can't be swept into story commits by the unit's `git add -A`;
`bmad-loop init` also gitignores _bmad/render/ for in-place runs.
- The shim HALTs on any failure BEFORE the workflow's HALT protocol is
loaded, so a broken environment (no uv, no central config, missing
render.py) yields one result-less Stop per story with no spec status
ever written. A renderer preflight (validate + run/sweep/resume start)
now fails loudly instead — gated on the installed SKILL.md actually
being the render shim, so pre-render installs see zero new checks and
byte-stable validate output.
- `validate --render-probe` (opt-in) executes the real renderer against
the project to surface render-time HALTs (#2588: missing {{.var}}
keys, unparseable override layers) before a run burns a story.
- validate warns (never fails) when the four-layer central TOML and the
legacy _bmad/bmm/config.yaml disagree on implementation_artifacts
(the renderer follows the TOML, the orchestrator reads the yaml —
TOML-first migration tracked in #154), and once when a project has
already committed _bmad/render/** (excludes can't shield tracked
files; `git rm -r --cached` remediation printed).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
WalkthroughRenderer-era preflight, render probing, TOML artifact parity warnings, and worktree ChangesRenderer validation and artifact parity
Worktree configuration seeding and render shielding
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Validator as bmad-loop validate
participant Support as missing_renderer_support
participant UV as uv
participant Renderer as render.py
Validator->>Support: check render.py, uv, and _bmad/config.toml
Validator->>UV: execute uv run render.py
UV->>Renderer: start renderer probe
Renderer-->>Validator: dispatch output or HALT details
Possibly related issues
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What upstream changed
BMAD-METHOD 64157d39 (#2587) made
bmad-dev-auto's SKILL.md a two-line shim —uv run {skill-root}/render.py, follow its stdout; on ANY failure "report what it printed and HALT". The old SKILL.md body moved toworkflow.md, rendered into{project-root}/_bmad/render/bmad-dev-auto/with config values and absolute paths baked in at render time.render.pyfinds{project-root}by walking UP from the session cwd to the first_bmad/directory and requires the post-#2285 central_bmad/config.toml. Follow-up 1cd4a7f5 (#2588, upstream HEAD) hardened it: a{{.var}}referenced by the templates but missing from the merged config, or a present-but-unparseable customization layer, now hard-HALTs.The completion contract bmad-loop parses is unchanged (verified against the diff):
## Auto Run Result,Status:line, frontmatter statuses,baseline_revision, thebmad-dev-auto-result-fallback prefix, folder+id dispatch, and the"folder+id dispatch"stories-probe literal all survive; every preflight marker file still exists.devcontract.pyis untouched. The breakage is environmental, in two critical shapes:<project>/.bmad-loop/runs/<id>/worktrees/…and never carried a_bmad/(defaultworktree_seed = []), so render.py silently adopted the main checkout's_bmad/: rendered workflows baked main-checkout absolute artifact paths (deferred-work appends, no-spec fallback artifacts, and step-01 context all escaped the worktree — fallback artifacts landing where_artifact_dirsnever looks), and every parallel session raced on one shared render dir that render.py delete-rewrites per invocation.workflow.md's HALT protocol is ever loaded, so a broken environment (nouv, no_bmad/config.toml, missingrender.py, or a #2588 config HALT) writes no spec status at all — every story becomes a result-less Stop (the cascade fix(adapters): bound dev/review stall nudges + diagnose result-less Stops #151's breadcrumbs diagnose, one story at a time).What this PR does
_bmadmerge-seed inprovision_worktree: per-FILE copy-when-absent of the main repo's_bmad/into the worktree (a committed_bmad/keeps every tracked file; the gitignored*.user.tomllayers — whose absence hard-HALTs render.py since #2588 — are filled in), never seeding the regeneratedrender/. Shield rels follow the existing "shield exactly what we wrote" doctrine: one anchored/_bmadwhen the checkout had none, per-file rels when merging./_bmad/render/always excluded (git-common-dirinfo/exclude), so session-rendered output (machine-absolute paths baked in) can't be swept into story commits by the unit'sgit add -A;bmad-loop initalso gitignores_bmad/render/for in-place (isolation = "none") runs.install.missing_renderer_support) invalidateand at run/sweep/resume start:render.pynext to the shim,uvon PATH,_bmad/config.tomlpresent. Gated on the installed SKILL.md actually containingrender.py— pre-render installs get zero new checks and byte-stable validate output.validate --render-probe(opt-in): executes the realuv run render.pyagainst the project; pass = theread and follow …dispatch line. Surfaces #2588 render-time HALTs before a run. Side effect documented in--help(rewrites the regenerated_bmad/render/bmad-dev-auto/cache).bmm/config.yamldesync onimplementation_artifacts(bmadconfig.toml_artifact_parity, mirroring render.py's exact merge precedence — deep-merge layers, then[modules.bmm]beats[core]; TOML-first migration tracked in bmadconfig: read the four-layer central TOML as primary, legacy bmm/config.yaml as fallback #154), and a one-time "you have_bmad/render/**committed —git rm -r --cachedit" hint (excludes can't shield tracked files).Verification
trunk checkclean. New coverage: seed/merge/shield/symlink-escape, renderer-support matrix (incl. uv-missing reported once across trees), probe pass/HALT via a fake-uv launcher (no test executes real uv — Windows CI safe), an end-to-end engine test proving a committed-_bmadproject's worktree gets the gitignored user layer seeded and the session's render residue never reaches the story commit, and TOML-parity precedence tests.validatedetects the shim and passes the preflight;validate --render-proberan the real renderer via uv and produced its dispatch line; the rendered step-04 confirms the absolute-path baking the seed protects against.Follow-ups
_bmad/render/; render.py's walk-up could stop at a git-worktree/repo boundary as defense-in-depth. Filed separately.Summary by CodeRabbit
New Features
render.py,uv, and centralized configuration.validate --render-probeto detect render-time failures and configuration issues.Bug Fixes
Documentation